#ifndef __FGC_H_
#define __FGC_H_

#include <map>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>

using namespace std;

typedef enum {
    tINT,
    tINTARR,
    tFLOAT,
    tFLOATARR,
    tVOID
} id_type;

typedef enum {
    lVOID,
    lFUNC,
    lJMP
} label_type;

#define BASE_TYPE(x) ((x) == tINTARR ? tINT : (((x) == tFLOATARR ? tFLOAT : (x))))

#define EXP_TYPE(x) (((x) == tINT || (x) == tFLOAT) ? 1 : 0)

#define ARR_TYPE(x) (((x) == tINTARR || (x) == tFLOATARR) ? 1 : 0)

#define FUNC_TYPE(x) (((x) == tINT || (x) == tFLOAT || (x) == tVOID) ? 1 : 0)

typedef struct {
    char *name;
    int index;
    id_type type;
} EXP_t;

typedef struct {
    id_type type;
    union {
        int i;
        float f;
    } value;
} CONST_t;

typedef struct _PARA_NODE_t {
    EXP_t para;
    struct _PARA_NODE_t *next;
} PARA_NODE_t;

typedef struct {
    PARA_NODE_t *head;
    PARA_NODE_t *tail;
    int size;
} PARA_LIST_t;

typedef struct {
    int label;
    int index;
    id_type type;
    int defined;
    int is_system;
    PARA_LIST_t *para_list;
} FUNC_t;

typedef struct {
    int label_1;
    int label_2;
    int label_3;
} FOR_t;

typedef map <string, EXP_t> id_table_t;
typedef map <string, FUNC_t> func_table_t;

#endif
